<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace buwang\util\appcurd;

use buwang\util\CommonTool;
use Symfony\Component\Filesystem\Filesystem;

/**
 * 自动创建应用
 */
class AppGenerate
{
    /**
     * 应用根目录
     * @var string
     */
    protected $rootDir;

    /**
     * 当前目录
     * @var string
     */
    protected $dir;

    /**
     * 生成文件目录
     * @var string
     */
    protected $file_directory;

    /**
     * 应用目录
     * @var string
     */
    protected $app_path;

    /**
     * 压缩文件目录
     * @var string
     */
    protected $zip_dir;

    /**
     * 相关生成文件
     * @var array
     */
    protected $fileList = [];

    /**
     * 分隔符
     * @var string
     */
    protected $DS = DIRECTORY_SEPARATOR;

    /**
     * 初始化
     * BuildCurd constructor.
     */
    public function __construct()
    {
        $this->rootDir = root_path();
        $this->dir = __DIR__;
        $this->file_directory = "{$this->rootDir}runtime{$this->DS}generateapp";
        $this->app_path = "{$this->rootDir}runtime";
        $this->zip_dir = "generateapp";
        return $this;
    }

    /**
     * 获取相关的文件
     * @return array
     */
    public function getFileList()
    {
        return $this->fileList;
    }
    /**
     * 初始化-应用
     * @return $this
     */
    public function renderApp($data)
    {
        //version
        $this->renderAppVersion($data);
        // 控制器
        $this->renderController($data);
        // 模型
        $this->renderModel($data);
        // 路由
        $this->renderRoute($data);
        // view
        $this->renderView($data);
        // install
        $this->renderInstall($data);
        // uninstall
        $this->renderUninstall($data);

        return $this;
    }

    /**
     * 初始化version
     * @return $this
     */
    protected function renderAppVersion($data)
    {
        $versionFile = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}config{$this->DS}version.php";

        $controllerValue = CommonTool::replaceTemplate(
            $this->getTemplate("config{$this->DS}version"),
            [
                //'controllerNamespace' => "app\\{$this->appName}\\controller{$extendNamespace}",
                'types' => $data['types'],
                'version' => $data['version'],
                'title' => $data['title'],
                'describe' => $data['describe'],
                'is_openapp' => $data['is_openapp'],
                'is_manage' => $data['is_manage'],
                'is_wechat_pay' => $data['is_wechat_pay'],
                'is_alipay_pay' => $data['is_alipay_pay'],
                'prefix' => $data['app_dir'],
            ]);
        $this->fileList[$versionFile] = $controllerValue;
        return $this;
    }

    /**
     * 初始化controller
     * @param $data
     * @return $this
     */
    protected function renderController($data)
    {
        $controllerFile = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}controller{$this->DS}admin{$this->DS}Index.php";
        $controllerValue = CommonTool::replaceTemplate(
            $this->getTemplate("controller{$this->DS}admin{$this->DS}Index"),
            [
                //'controllerNamespace' => "app\\{$this->appName}\\controller{$extendNamespace}",
                'controllerNamespace' => "app\\{$data['app_dir']}\\controller\\admin",
            ]);
        $this->fileList[$controllerFile] = $controllerValue;
        return $this;
    }

    /**
     * 初始化model
     * @param $data
     * @return $this
     */
    protected function renderModel($data)
    {
        $modelFile = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}model{$this->DS}system{$this->DS}Config.php";
        $modelValue = CommonTool::replaceTemplate(
            $this->getTemplate("model{$this->DS}system{$this->DS}Config"),
            [
                //'controllerNamespace' => "app\\{$this->appName}\\controller{$extendNamespace}",
                'modelNamespace' => "app\\{$data['app_dir']}\\model\\system",
                'modelName' => "Config",
                'tableName' => "config",
            ]);
        $this->fileList[$modelFile] = $modelValue;

        $modelFile2 = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}model{$this->DS}system{$this->DS}ConfigGroup.php";
        $modelValue2 = CommonTool::replaceTemplate(
            $this->getTemplate("model{$this->DS}system{$this->DS}Config"),
            [
                //'controllerNamespace' => "app\\{$this->appName}\\controller{$extendNamespace}",
                'modelNamespace' => "app\\{$data['app_dir']}\\model\\system",
                'modelName' => "ConfigGroup",
                'tableName' => "config_group",
            ]);
        $this->fileList[$modelFile2] = $modelValue2;

        $modelFile3 = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}model{$this->DS}system{$this->DS}ConfigGroupData.php";
        $modelValue3 = CommonTool::replaceTemplate(
            $this->getTemplate("model{$this->DS}system{$this->DS}Config"),
            [
                //'controllerNamespace' => "app\\{$this->appName}\\controller{$extendNamespace}",
                'modelNamespace' => "app\\{$data['app_dir']}\\model\\system",
                'modelName' => "ConfigGroupData",
                'tableName' => "config_group_data",
            ]);
        $this->fileList[$modelFile3] = $modelValue3;

        $modelFile4 = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}model{$this->DS}system{$this->DS}ConfigTab.php";
        $modelValue4 = CommonTool::replaceTemplate(
            $this->getTemplate("model{$this->DS}system{$this->DS}Config"),
            [
                //'controllerNamespace' => "app\\{$this->appName}\\controller{$extendNamespace}",
                'modelNamespace' => "app\\{$data['app_dir']}\\model\\system",
                'modelName' => "ConfigTab",
                'tableName' => "config_tab",
            ]);
        $this->fileList[$modelFile4] = $modelValue4;
        return $this;
    }

    /**
     * 初始化route
     * @param $data
     * @return $this
     */
    protected function renderRoute($data)
    {
        $routeFile = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}route{$this->DS}admin.php";
        $routeValue =  $this->getTemplate("route{$this->DS}admin");
        $this->fileList[$routeFile] = $routeValue;
        return $this;
    }

    /**
     * 初始化 view
     * @param $data
     * @return $this
     */
        protected function renderView($data)
    {
        $viewFile = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}view{$this->DS}admin{$this->DS}index{$this->DS}index.html";
        $viewValue =  $this->getTemplate("view{$this->DS}admin{$this->DS}index{$this->DS}index");
        $this->fileList[$viewFile] = $viewValue;
        return $this;
    }

    /**
     * 初始化 install
     * @param $data
     * @return $this
     */
    protected function renderInstall($data)
    {
        $installFile = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}install{$this->DS}install.sql";
        $installValue = CommonTool::replaceTemplate(
            $this->getTemplate("install{$this->DS}install"),
            [
                'appName' => "{$data['app_dir']}",
            ]);
        $this->fileList[$installFile] = $installValue;

        $installFile2 = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}install{$this->DS}listen.php";
        $installValue2 =  $this->getTemplate("install{$this->DS}listen");
        $this->fileList[$installFile2] = $installValue2;

        $installFile3 = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}install{$this->DS}menu.php";
        $installValue3 = CommonTool::replaceTemplate(
            $this->getTemplate("install{$this->DS}menu"),
            [
                'appName' => "{$data['app_dir']}",
            ]);
        $this->fileList[$installFile3] = $installValue3;

        $installFile4 = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}install{$this->DS}static{$this->DS}logo.png";
        $installValue4 =  $this->getImageFile("install{$this->DS}static{$this->DS}logo");
        $this->fileList[$installFile4] = $installValue4;

        $installFile5 = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}install{$this->DS}static{$this->DS}style.png";
        $installValue5 =  $this->getImageFile("install{$this->DS}static{$this->DS}style");
        $this->fileList[$installFile5] = $installValue5;
        return $this;
    }

    /**
     * 初始化 uninstall
     * @param $data
     * @return $this
     */
    protected function renderUninstall($data)
    {
        $installFile = "{$this->file_directory}{$this->DS}{$data['app_dir']}{$this->DS}uninstall{$this->DS}uninstall.sql";
        $installValue = CommonTool::replaceTemplate(
            $this->getTemplate("uninstall{$this->DS}uninstall"),
            [
                'appName' => "{$data['app_dir']}",
            ]);
        $this->fileList[$installFile] = $installValue;
        return $this;
    }



    /**
     * 获取对应的模板信息
     * @param $name
     * @return false|string
     */
    protected function getTemplate($name)
    {
        return file_get_contents("{$this->dir}{$this->DS}templates{$this->DS}{$name}.code");
    }

    /**
     * 获取图片文件
     * @param $name
     * @return false|string
     */
    protected function getImageFile($name)
    {
        return file_get_contents("{$this->dir}{$this->DS}templates{$this->DS}{$name}.png");
    }

    /**
     * 开始生成-下载
     * @return array
     */
    public function createNew()
    {
        // 删除目录下所有文件
        $dirPath = root_path($this->file_directory);
        $fs = new Filesystem();
        $fs->remove($dirPath);

        //$this->check();
        foreach ($this->fileList as $key => $val) {
            // 判断文件夹是否存在,不存在就创建
            $fileArray = explode($this->DS, $key);
            array_pop($fileArray);
            $fileDir = implode($this->DS, $fileArray);
            if (!is_dir($fileDir)) {
                mkdir($fileDir, 0775, true);
            }

            // 写入
            file_put_contents($key, $val);
            //修改生成文件权限为 775
            chmod($key, 0775);
        }
        return array_keys($this->fileList);
    }

    /**
     * 压缩文件
     */
    public function zipFile()
    {
        $generatePath =$this->file_directory.$this->DS;
        $appPath = $this->app_path.$this->DS;

        $fileName = 'app-' . date('YmdHis') . '.zip';
        $this->zipTempName = $fileName;
        $this->zipTempPath = $generatePath . $fileName;
        $zip = new \ZipArchive();
        $zip->open($this->zipTempPath, \ZipArchive::CREATE);
        $this->addFileZip($appPath, $this->zip_dir, $zip);
        $zip->close();
        return true;
    }

    /**
     * 往压缩包写入文件
     */
    public function addFileZip($basePath, $dirName, $zip)
    {
        $handler = opendir($basePath . $dirName);
        while (($filename = readdir($handler)) !== false) {
            if ($filename != '.' && $filename != '..') {
                if (is_dir($basePath . $dirName . '/' . $filename)) {
                    // 当前路径是文件夹
                    $this->addFileZip($basePath, $dirName . '/' . $filename, $zip);
                } else {
                    // 写入文件到压缩包
                    $zip->addFile($basePath . $dirName . '/' . $filename, $dirName . '/' . $filename);
                }
            }
        }
        closedir($handler);
        return true;
    }

//    /**
//     * 初始化version
//     * @return $this
//     */
//    protected function renderAppVersion($data)
//    {
//        $routeFile = "{$this->rootDir}runtime{$this->DS}generate1{$this->DS}{$data['dir']}{$this->DS}route{$this->DS}route.php";
//        $generatedRoute = $this->renderAppVersionContent($data['types'],$data['version'],$data['title'],$data['describe'],$data['is_openapp'],
//            $data['is_manage'],$data['is_wechat_pay'],$data['is_alipay_pay'],$data['dir']);
//        $this->fileList[$routeFile] = $generatedRoute;
//        return $this;
//    }
//
//    /**
//     * 生成version文件
//     * @param $types
//     * @param $version
//     * @param $title
//     * @param $describe
//     * @param $is_openapp
//     * @param $is_manage
//     * @param $is_wechat_pay
//     * @param $is_alipay_pay
//     * @param $database_prefix
//     * @return string
//     */
//    public function renderAppVersionContent($types,$version,$title,$describe,$is_openapp,$is_manage,$is_wechat_pay,$is_alipay_pay,$database_prefix){
//        $content = <<<EOT
//            <?php
//            /**
//             * types types 应用类型 参数：mini_program=微信小程序,app=APP(安卓和IOS),h5=H5移动端网页,official=公众号,system=系统,tt_program=头条小程序
//             * version    应用版本号
//             * name 应用名称
//             * describe 应用描述
//             * is_openapp 开放平台应用  1平台、0独立
//             * is_manage  启用总平台管理  0关闭1启用
//             * is_wechat_pay 微信支付  0、1
//             * is_alipay_pay 支付宝支付  0、1
//             */
//
//            return [
//                'types'         => '$types',
//                'version'       => '$version',
//                'title'         => '$title',
//                'describe'      => "$describe",
//                'is_openapp'    => $is_openapp,
//                'is_manage'     => $is_manage,
//                'is_wechat_pay' => $is_wechat_pay,
//                'is_alipay_pay' => $is_alipay_pay,
//                'database'      => [
//                    'prefix'        => '$database_prefix'
//                ]
//            ];
//            EOT;
//
//        return $content;
//    }

}